#!/usr/bin/perl
# 2010/07/16 Crop FISH image from avi file	(Hideki Tanizawa)

use strict;
use warnings;
use IO::File;
use Getopt::Std;
use Carp qw(croak);
$| = 0;

if(@ARGV != 8 or $ARGV[0] eq '--help'){
	die "Usage : $0 -i [avi file] -o [output image name] -g [green file] -r [red file]\n";
}

my $lineImg = 'line.png';

# get options
my %opt;
getopts("i:o:g:r:M", \%opt);
my $source = $opt{i};
my $outImage = $opt{o};
my $greeFile = $opt{g};
my $redFile = $opt{r};
my $IamMacUser = $opt{M};

(my $distanceFile = 'dis_' . $outImage) =~ s/\.png/.txt/;


#---------------------------------------
# convert avi 2 png
#---------------------------------------
if(-d "tmp"){
	unlink glob("./tmp/*") or die "cannot remove file in tmp directory: $!";
}else{
	mkdir "tmp" or die "cannot make tmp directory $!";
}
my $convert = "convert $source ./tmp/img%03d.png";
my $cmd = qx/$convert/;

#---------------------------------------
# get coordinate
#---------------------------------------
my $MAXgreen = 0;
my $MAXred = 0;
my %green = &readCoordinate($greeFile, \$MAXgreen);
my %red = &readCoordinate($redFile, \$MAXred);
if($MAXgreen != $MAXred){
	die "green and red has different spot number\n";
}
sub readCoordinate{
	my ($file, $MAX) = @_;
	my %hash;
	my $fh = IO::File->new($file) or die "cannot open $file: $!";
	while($_ = $fh->getline()){
		s/\r?\n//;
		unless(m/^\d/){
			next;
		}
		my ($num, $x, $y, @other) = split /\t/;
		$hash{$num} = [$x, $y];
		$$MAX++;
	}
	$fh->close();
	return %hash;
}


#---------------------------------------
# convert image
#---------------------------------------
# output distance file
my $fh_dis = IO::File->new($distanceFile, 'w') or die "cannot write distance file: $!";

# Image Magick module
require Image::Magick;
my $status;
my $pi = atan2(1,1)*4;
my $mix = Image::Magick->new;
for(my $i = 1; $i <= $MAXgreen; $i++){
	my $imageName = sprintf "./tmp/img%03d.png", $i - 1;
	my $imageOutName = sprintf "./tmp/img%03d_m.png", $i -1;
	my $image = Image::Magick->new;
	$status = $image->Read($imageName);
	warn "$status" if "$status";
	
	# current size
	my ($wb, $hb) = $image->Get('width', 'height');
	# rotate image
	my $height = $green{$i}->[0] - $red{$i}->[0];
	my $width = $green{$i}->[1] - $red{$i}->[1];
	my $degree = atan2($height, $width)*180/$pi;
	$status = $image->Rotate(degrees=>$degree, background=>"black");
	warn "$status" if "$status";
	
	# distance
	my $distance = sqrt($height**2 + $width**2);
	$fh_dis->printf("%d\t%f\n", $i, $distance);
	
	# rotated size
	my ($wr, $hr) = $image->Get('width', 'height');
	
	# coordinate
	my $oldAngle = atan2($red{$i}->[1] - $hb/2, $red{$i}->[0] - $wb/2)*180/$pi;
	my $newAngle = $oldAngle + $degree;
	my $radius = sqrt(($red{$i}->[1] - $hb/2)**2 + ($red{$i}->[0] - $wb/2)**2);
	my $newX = $radius*cos($newAngle*$pi/180) + $wr/2;
	my $newY = $radius*sin($newAngle*$pi/180) + $hr/2;	
	
	# crop
	my $cropWidth = 24;
	my $cropHeight = 70;
	my $parameter = sprintf "%dx%d+%d+%d", $cropWidth, $cropHeight, $newX-12, $newY - 20;	

	$status = $image->Crop($parameter);
	warn "$status" if "$status";
	
	$status = $image->Write($imageOutName);
	warn "$status" if "$status";
	
	$status = $mix->Read($imageOutName);
	warn "$status" if "$status";
	
	$status = $mix->Read($lineImg);
	warn "$status" if "$status";
}

$fh_dis->close();

# merge image
my $connect = $mix->Append(stack=>'false');
warn "$status" if "$status";
$status = $connect->Write($outImage);
warn "$status" if "$status";

# remove temporary directory
unlink glob("./tmp/*") or die "cannot remove file in tmp directory: $!";
rmdir "tmp" or die "cannot remove tmp directory: $!";